package com.daigoudao.web.action;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.daigoudao.util.Constants;
import com.daigoudao.util.NumberUtil;
import com.daigoudao.web.common.BasePageAction;
import com.daigoudao.web.model.CanBuyModel;
import com.daigoudao.web.model.Cart;
import com.daigoudao.web.model.CartItem;
import com.daigoudao.web.model.UserAddrModel;
import com.daigoudao.web.model.UserModel;
import com.daigoudao.web.service.ICanBuyService;
import com.daigoudao.web.service.IUserAddrService;
import com.daigoudao.web.service.IUserService;
import com.danga.MemCached.MemCachedClient;

/**
 * 购物车操作类
 * 
 * @author zheng
 * 
 */
public class CartAction extends BasePageAction {

	private static final long serialVersionUID = -9016329522573531336L;

	private static Logger logger = LoggerFactory.getLogger(CartAction.class);

	private ICanBuyService canBuyService;

	private IUserService userService;

	private IUserAddrService userAddrService;

	private int number;

	private double totalPrice;

	private String backUrl;

	private int brokerId;

	private int productId;

	private int[] productIds;

	/**
	 * 经纪人列表
	 */
	private List<UserModel> brokers;

	private List<UserAddrModel> userAddrs;

	private UserAddrModel defaultAddr;

	private Cart cart;

	private CanBuyModel product;

	private MemCachedClient memcachedClient;

	/**
	 * 经纪人信息
	 */
	private UserModel broker;

	/**
	 * 进行结算的购物项
	 */
	private List<CartItem> items;

	private double logisticCharge;

	/**
	 * 跳至购物车页面
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String initCart() {
		if (!isLogin()) {
			session.put(Constants.URL, "cart.htm");
			return LOGIN;
		}
		cart = getCart(memcachedClient, getUserLogin().getUserid());
		// 刷新代购车中商品的价格等信息
		try {
			refreshCart(memcachedClient, cart);
			Set<Integer> brokerIds = cart.getBrokerIds();
			brokers = generateBrokers(brokerIds);
		} catch (Exception e) {
			logger.error("get broker info error.", e);
			return ERROR;
		}
		return SUCCESS;
	}

	/**
	 * 将代购信息加入至购物车
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String addItem() {
		int userId = 0;
		if (isLogin()) {
			userId = getUserLogin().getUserid();
		}
		CanBuyModel product = null;
		try {
			product = canBuyService.queryCanBuyDetail(productId);
		} catch (Exception e) {
			logger.error("add item to cart error.", e);
			ajaxMsg = "系统忙，请稍候再试。";
			return SUCCESS;
		}
		if (product == null || product.getStatus() != 0) {
			ajaxMsg = "对不起，该商品不存在或已下线，无法加入至代购车";
		} else {
			try {
				cart = getCart(memcachedClient, userId);
				cart.add(product, number);
				addCart(memcachedClient, cart, userId);
			} catch (Exception e) {
				logger.error("add item error", e);
			}
		}
		session.put(Constants.CART, cart.getCount());
		return SUCCESS;
	}

	public String changeItem() {
		cart = getCart(memcachedClient, getUserLogin().getUserid());
		cart.setNumber(id, productId, number);
		addCart(memcachedClient, cart, getUserLogin().getUserid());
		return SUCCESS;
	}

	/**
	 * 删除购物项
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String delItem() {
		cart = getCart(memcachedClient, getUserLogin().getUserid());
		cart.delItem(brokerId, productId);
		addCart(memcachedClient, cart, getUserLogin().getUserid());
		session.put(Constants.CART, cart.getCount());
		return SUCCESS;
	}

	/**
	 * 结算
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String settlement() {
		UserModel userModel = getUserLogin();
		if (userModel == null) {
			StringBuilder requestUrl = new StringBuilder("settlement.htm");
			requestUrl.append("?brokerId=").append(brokerId);
			for (int productId : productIds) {
				requestUrl.append("&").append(productId);
			}
			session.put(Constants.URL, requestUrl);
			return LOGIN;
		}
		try {
			userAddrs = getUserAddrs(userModel);
		} catch (Exception e) {
			logger.error("settlement error.", e);
			return ERROR;
		}

		Cart cart = getCart(memcachedClient, userModel.getUserid());
		broker = userService.getUserBaseInfoByID(brokerId);
		items = cart.getItems(brokerId, productIds);

		// 计算运费
		logisticCharge = calcLogisticCharge();

		// 计算总价
		totalPrice = calcTotalPrice();

		backUrl = "cart.htm";
		return SUCCESS;
	}

	/**
	 * 计算运费
	 * 
	 * @return
	 */
	private double calcLogisticCharge() {
		double maxFirstCost = 0;
		int index = 0;
		for (int i = 0; i < items.size(); i++) {
			if (maxFirstCost < items.get(i).getLogistics().getPrice()) {
				maxFirstCost = items.get(i).getLogistics().getPrice();
				index = i;
			}
		}
		double logisticCharge = maxFirstCost * items.get(index).getNumber();
		for (int i = 0; i < items.size(); i++) {
			if (i != index) {
				logisticCharge += items.get(i).getNumber()
						* items.get(i).getLogistics().getContinuedPrice();
			}
		}
		return logisticCharge;
	}

	/**
	 * 清除代购车
	 */
	@SuppressWarnings("unchecked")
	public String clear() {
		cart = new Cart();
		addCart(memcachedClient, cart, getUserLogin().getUserid());
		session.put(Constants.CART, 0);
		return SUCCESS;
	}

	/**
	 * 生成经纪人信息
	 * 
	 * @param brokerIds
	 * @return
	 */
	private List<UserModel> generateBrokers(Set<Integer> brokerIds)
			throws Exception {
		List<UserModel> brokers = new ArrayList<UserModel>();
		for (int brokerId : brokerIds) {
			brokers.add(userService.getUserBaseInfoByID(brokerId));
		}
		return brokers;
	}

	/**
	 * 刷新代购车
	 * 
	 * @throws Exception
	 */
	private void refreshCart(MemCachedClient memcachedClient, Cart cart)
			throws Exception {
		Iterator<Map<Integer, CartItem>> iterator = cart.getItems().values()
				.iterator();
		while (iterator.hasNext()) {
			Map<Integer, CartItem> subItems = iterator.next();
			Iterator<CartItem> subIterator = subItems.values().iterator();
			while (subIterator.hasNext()) {
				CartItem cartItem = subIterator.next();
				CanBuyModel product = canBuyService.queryCanBuyDetail(cartItem
						.getProductId());
				if (product == null || product.getStatus() != 0) {
					subIterator.remove();
				} else {
					cartItem.changeItem(product);
				}
			}
			if (subItems.size() == 0) {
				iterator.remove();
			}
		}
		addCart(memcachedClient, cart, getUserLogin().getUserid());
	}

	private double calcTotalPrice() {
		double totalPrice = 0;
		for (CartItem item : items) {
			totalPrice += item.getSubtotal();
		}
		totalPrice += logisticCharge;
		return totalPrice;
	}

	public void setCanBuyService(ICanBuyService canBuyService) {
		this.canBuyService = canBuyService;
	}

	public int getNumber() {
		return number;
	}

	public void setNumber(int number) {
		this.number = number;
	}

	public List<UserModel> getBrokers() {
		return brokers;
	}

	public List<UserAddrModel> getUserAddrs() {
		return userAddrs;
	}

	public void setUserAddrs(List<UserAddrModel> userAddrs) {
		this.userAddrs = userAddrs;
	}

	public UserAddrModel getDefaultAddr() {
		return defaultAddr;
	}

	public void setDefaultAddr(UserAddrModel defaultAddr) {
		this.defaultAddr = defaultAddr;
	}

	public void setUserAddrService(IUserAddrService userAddrService) {
		this.userAddrService = userAddrService;
	}

	private List<UserAddrModel> getUserAddrs(UserModel userModel) {
		List<UserAddrModel> userAddrs = userAddrService
				.getAddrListByUserID(userModel.getUserid());
		// 将默认地址调整至第一个
		UserAddrModel userAddrModel = null;
		for (int i = 0; i < userAddrs.size(); i++) {
			if (userAddrs.get(i).getDefaultAddr() == 1) {
				userAddrModel = userAddrs.remove(i);
				break;
			}
		}
		if (userAddrModel != null) {
			userAddrs.add(0, userAddrModel);
			defaultAddr = userAddrModel;
		}
		return userAddrs;
	}

	public double getTotalPrice() {
		return NumberUtil.getBigDecimal(totalPrice, Constants.SCALE)
				.doubleValue();
	}

	public String getBackUrl() {
		return backUrl;
	}

	public void setBackUrl(String backUrl) {
		this.backUrl = backUrl;
	}

	public Cart getCart() {
		return cart;
	}

	public void setCart(Cart cart) {
		this.cart = cart;
	}

	public CanBuyModel getProduct() {
		return product;
	}

	public void setProduct(CanBuyModel product) {
		this.product = product;
	}

	public void setMemcachedClient(MemCachedClient memcachedClient) {
		this.memcachedClient = memcachedClient;
	}

	public void setProductId(int productId) {
		this.productId = productId;
	}

	public int getProductId() {
		return productId;
	}

	public int[] getProductIds() {
		return productIds;
	}

	public void setProductIds(int[] productIds) {
		this.productIds = productIds;
	}

	public void setBrokerId(int brokerId) {
		this.brokerId = brokerId;
	}

	public int getBrokerId() {
		return brokerId;
	}

	public UserModel getBroker() {
		return broker;
	}

	public void setBroker(UserModel broker) {
		this.broker = broker;
	}

	public void setUserService(IUserService userService) {
		this.userService = userService;
	}

	public List<CartItem> getItems() {
		return items;
	}

	public double getLogisticCharge() {
		return NumberUtil.getBigDecimal(logisticCharge, Constants.SCALE)
				.doubleValue();
	}
}
